home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c++-part1 / 8544 < prev    next >
Encoding:
Text File  |  1996-08-05  |  3.8 KB  |  141 lines

  1. Newsgroups: comp.lang.pascal.misc,comp.lang.c++,comp.lang.c,comp.lang.pascal.borland
  2. Path: cwi.nl!dik
  3. From: dik@cwi.nl (Dik T. Winter)
  4. Subject: Re: Tough FACTORIAL math problem...
  5. Message-ID: <DMuJwF.734@cwi.nl>
  6. Sender: news@cwi.nl (The Daily Dross)
  7. Nntp-Posting-Host: chrysant.cwi.nl
  8. Organization: CWI, Amsterdam
  9. References: <4fr8be$ass@news.iconn.net> <4g0giv$94s@sun132.spd.dsccc.com>
  10. Date: Fri, 16 Feb 1996 02:21:51 GMT
  11.  
  12. In article <4g0giv$94s@sun132.spd.dsccc.com> kcline@sun132.spd.dsccc.com (Kevin Cline) writes:
  13.  
  14. [Note: at the end there is a complete explanation of the problem and the
  15. solution.  At first here follows a flamelet.]
  16.  
  17.  > Everyone had the right idea, which is to keep only the last digit
  18.  > and compute the change when multiplying by the next number
  19.  > in the factorial, but couldn't figure out what to do
  20.  > about the numbers that end in 5, since that introduces a new zero
  21.  > in the series.  The answer is simple; when multiplying by five,
  22.  > take half of the previous digit +-5 to make an even number.
  23.  
  24. But you did it only halfway, see below.
  25.  > 
  26.  > This works because 5 always follows 4, 4 x 5 = 20 (2),
  27.  > and 2 is half of 4.
  28.  
  29. It is well known that in all cases the number of 5's is far less than
  30. the number of 2's in the factorial; k.5^n where k does not contain a
  31. factor 5, follows k.2^n.
  32.  
  33.  >     int last_non_zero_digit_of_factorial(n) {
  34.  >       digit = 1;
  35.  >       for (int i = 2; i < n ; ++i) {
  36.  >     while (i % 10 == 0) i /= 10;
  37.  >     digit = table[digit-1][i-1];
  38.  >       }
  39.  >       return digit;
  40.  >     }
  41. I get (with main(){int i; for(i=1;i<=25;i++)printf("%d %d\n",i,ldof(i));}):
  42.  
  43. 1 1
  44. 2 1
  45. 3 2
  46. 4 0
  47. Memory fault(coredump)
  48.  
  49. After interchanging "digit-1" and "i-1" I get
  50. 1 1
  51. 2 1
  52. 3 2
  53. 4 6
  54. 5 4
  55. 6 8
  56. 7 8
  57. 8 6
  58. 9 8
  59. 10 2
  60. after which it loops forever.
  61.  
  62. Changing the loop so that it uses a new variable rather than the loop
  63. variable I get:
  64. 1 1
  65. 2 1
  66. 3 2
  67. 4 6
  68. 5 4
  69. 6 8
  70. 7 8
  71. 8 6
  72. 9 8
  73. 10 2
  74. 11 2
  75. 12 268566528
  76. Memory fault(coredump)
  77.  
  78. Changing the terminating loop condition to <= n gives me:
  79. 1 1
  80. 2 2
  81. 3 6
  82. 4 4
  83. 5 8
  84. 6 8
  85. 7 6
  86. 8 8
  87. 9 2
  88. 10 2
  89. 11 268566528
  90. Memory fault(coredump)
  91.  
  92. Changing the faulty fifth line of the intialization of table to
  93. {0, 6, 0, 2, 0, 8, 0, 4, 0 }, gives me:
  94. 1 1
  95. 2 2
  96. 3 6
  97. 4 4
  98. 5 2
  99. 6 2
  100. 7 4
  101. 8 2
  102. 9 8
  103. 10 8
  104. 11 268697600
  105. Memory fault(coredump)
  106.  
  107. Finally changing i1-1 in the indexing to i1%10-1 the program kept running,
  108. but it gives 6 as last digit for 15!.
  109.  
  110. Did you try your function?
  111.  
  112. [End of flamelet.]
  113.  
  114. What you and most other posters (except the one I saw in maple, and my
  115. own of course) forget is that if a number contains factors of 5 you have
  116. to be aware of all factors 5 plus the remainder divided by all those
  117. factors. 14! ends in 2, lets see what happens if you multiply by 15.
  118. First take the factor of 5; this will take 2 to 10 and a last digit
  119. of 1; but (as you already saw) that is not valid so the last digit will
  120. become 6.  Now you still have the remaining factor 3 which will take
  121. 6 to 8.  And, indeed, the last non-zero digit of 15! is 8.
  122.  
  123. Jochen Schoof's solution inherently used a similar table, but he ignored
  124. the possibility of multiple factors 5.  Which (in his case) did result
  125. for some factorials in odd last non-zero digits, and that can not happen
  126. (except for 0! and 1!).
  127.  
  128. Using only the last k digits of the factorial (excluding trailing zeros)
  129. and the last l digits of the multiplier will ultimately lead to a
  130. period.  (The proof is fairly simple.)  But the last non-zero digit of
  131. the factorial does not show a period; the increasing number of factors 5
  132. that can occur in a single number prevent this.  So, all such methods
  133. will fail at some stage.  Taking care of all individual factors 5 solves
  134. this.
  135.  
  136. But apparently this is a tough question indeed.  Even an old-timer like
  137. Jos Horsmeier fell into at least one of the traps.
  138. -- 
  139. dik t. winter, cwi, kruislaan 413, 1098 sj  amsterdam, nederland, +31205924098
  140. home: bovenover 215, 1025 jn  amsterdam, nederland; http://www.cwi.nl/~dik/
  141.